/*
 * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package com.sun.corba.se.impl.protocol;

import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;

import com.sun.corba.se.pept.protocol.ClientRequestDispatcher;

import com.sun.corba.se.spi.protocol.LocalClientRequestDispatcher;
import com.sun.corba.se.spi.protocol.LocalClientRequestDispatcherFactory;
import com.sun.corba.se.spi.protocol.CorbaServerRequestDispatcher;
import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry;

import com.sun.corba.se.spi.oa.ObjectAdapterFactory;

import com.sun.corba.se.spi.orb.ORB;

import com.sun.corba.se.impl.orbutil.ORBConstants;
import com.sun.corba.se.impl.orbutil.DenseIntMapImpl;

/**
 * This is a registry of all subcontract ID dependent objects.  This includes:
 * LocalClientRequestDispatcherFactory, ClientRequestDispatcher, ServerSubcontract, and
 * ObjectAdapterFactory.
 */
public class RequestDispatcherRegistryImpl implements RequestDispatcherRegistry {
    private ORB orb;

    protected int defaultId;                    // The default subcontract ID to use if
    // there is no more specific ID available.
    // This happens when invoking a foreign IOR.
    private DenseIntMapImpl SDRegistry;        // ServerRequestDispatcher registry
    private DenseIntMapImpl CSRegistry;        // ClientRequestDispatcher registry
    private DenseIntMapImpl OAFRegistry;       // ObjectAdapterFactory registry
    private DenseIntMapImpl LCSFRegistry;      // LocalClientRequestDispatcherFactory registry
    private Set objectAdapterFactories;        // Set of all ObjectAdapterFactory instances
    private Set objectAdapterFactoriesView;    // Read-only view of oaf instances
    private Map stringToServerSubcontract;     // Map from obect key string to
    // ServerSubcontract
    // for special bootstrap IORs

    public RequestDispatcherRegistryImpl(ORB orb, int defaultId) {
        this.orb = orb;
        this.defaultId = defaultId;
        SDRegistry = new DenseIntMapImpl();
        CSRegistry = new DenseIntMapImpl();
        OAFRegistry = new DenseIntMapImpl();
        LCSFRegistry = new DenseIntMapImpl();
        objectAdapterFactories = new HashSet();
        objectAdapterFactoriesView = Collections.unmodifiableSet(objectAdapterFactories);
        stringToServerSubcontract = new HashMap();
    }

    public synchronized void registerClientRequestDispatcher(
            ClientRequestDispatcher csc, int scid) {
        CSRegistry.set(scid, csc);
    }

    public synchronized void registerLocalClientRequestDispatcherFactory(
            LocalClientRequestDispatcherFactory csc, int scid) {
        LCSFRegistry.set(scid, csc);
    }

    public synchronized void registerServerRequestDispatcher(
            CorbaServerRequestDispatcher ssc, int scid) {
        SDRegistry.set(scid, ssc);
    }

    public synchronized void registerServerRequestDispatcher(
            CorbaServerRequestDispatcher scc, String name) {
        stringToServerSubcontract.put(name, scc);
    }

    public synchronized void registerObjectAdapterFactory(
            ObjectAdapterFactory oaf, int scid) {
        objectAdapterFactories.add(oaf);
        OAFRegistry.set(scid, oaf);
    }

    // **************************************************
    // Methods to find the subcontract side subcontract
    // **************************************************

    // Note that both forms of getServerRequestDispatcher need to return
    // the default server delegate if no other match is found.
    // This is essential to proper handling of errors for
    // malformed requests.  In particular, a bad MAGIC will
    // result in a lookup in the named key table (stringToServerSubcontract),
    // which must return a valid ServerRequestDispatcher.  A bad subcontract ID
    // will similarly need to return the default ServerRequestDispatcher.

    public CorbaServerRequestDispatcher getServerRequestDispatcher(int scid) {
        CorbaServerRequestDispatcher sdel =
                (CorbaServerRequestDispatcher) (SDRegistry.get(scid));
        if (sdel == null)
            sdel = (CorbaServerRequestDispatcher) (SDRegistry.get(defaultId));

        return sdel;
    }

    public CorbaServerRequestDispatcher getServerRequestDispatcher(String name) {
        CorbaServerRequestDispatcher sdel =
                (CorbaServerRequestDispatcher) stringToServerSubcontract.get(name);

        if (sdel == null)
            sdel = (CorbaServerRequestDispatcher) (SDRegistry.get(defaultId));

        return sdel;
    }

    public LocalClientRequestDispatcherFactory getLocalClientRequestDispatcherFactory(
            int scid) {
        LocalClientRequestDispatcherFactory factory =
                (LocalClientRequestDispatcherFactory) (LCSFRegistry.get(scid));
        if (factory == null) {
            factory = (LocalClientRequestDispatcherFactory) (LCSFRegistry.get(defaultId));
        }

        return factory;
    }

    public ClientRequestDispatcher getClientRequestDispatcher(int scid) {
        ClientRequestDispatcher subcontract =
                (ClientRequestDispatcher) (CSRegistry.get(scid));
        if (subcontract == null) {
            subcontract = (ClientRequestDispatcher) (CSRegistry.get(defaultId));
        }

        return subcontract;
    }

    public ObjectAdapterFactory getObjectAdapterFactory(int scid) {
        ObjectAdapterFactory oaf =
                (ObjectAdapterFactory) (OAFRegistry.get(scid));
        if (oaf == null)
            oaf = (ObjectAdapterFactory) (OAFRegistry.get(defaultId));

        return oaf;
    }

    public Set getObjectAdapterFactories() {
        return objectAdapterFactoriesView;
    }
}
